package com.res.common.controller;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.res.simulator.handler.CommonFileHandler;
import com.res.simulator.handler.RecordAndPlaySearchResultHandler;
import com.res.simulator.handler.RecordedAPIInvocationHandler;
import com.res.simulator.model.RecordAndPlayModel;
import com.res.simulator.view.SearchResultView;
import com.res.simulator.view.RecordAndPlayExecutionResultView;
import com.res.system.common.SessionRegistry;

@Controller
@SessionAttributes
public class RecordAndPlayPageController extends BaseController {

    private static final Logger logger = Logger.getLogger(RecordAndPlayPageController.class);
	
    @RequestMapping("/recordandplay_execute_result")
    public String recordAndPlayExecuteResult(@ModelAttribute("RecordAndPlayModel") final RecordAndPlayModel model, final BindingResult result) {

        getSession().setAttribute(SessionRegistry.RECORD_AND_PLAY_HISTORY_RECORD_SELECTION, new HashSet<String>());
        
        return "recordandplaylayout";
    }

    @RequestMapping(value = "/recordandplay_result", method = RequestMethod.GET, params = {"searchHistory"})
    protected String search(@ModelAttribute("RecordAndPlayModel") final RecordAndPlayModel model, final BindingResult result) throws Exception {

        final RecordAndPlaySearchResultHandler handler = new RecordAndPlaySearchResultHandler();
        final List<SearchResultView> resultViewList = handler.process(model);

        getSession().setAttribute(SessionRegistry.RECORD_AND_PLAY_SERACH_VIEW, resultViewList);

        return "redirect:recordandplay_execute_result.htm";
    }

    /**
     * 
     * 
     * @param model
     * @param result
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/recordandplay_result", method = RequestMethod.GET, params = {"Execute"})
    protected String execute(@ModelAttribute("RecordAndPlayModel") final RecordAndPlayModel model, final BindingResult result) throws Exception {

        final Set<String> recordedIdSet = (Set<String>) getSession().getAttribute(SessionRegistry.RECORD_AND_PLAY_HISTORY_RECORD_SELECTION);
        final List<SearchResultView> serchResultViewList = (List<SearchResultView>) getSession().getAttribute(SessionRegistry.RECORD_AND_PLAY_SERACH_VIEW);

        final List<SearchResultView> executionReadyList = new ArrayList<SearchResultView>();

        if (null != serchResultViewList && null != recordedIdSet && recordedIdSet.size() > 0) {

            for (final SearchResultView searchResultView : serchResultViewList) {

                if (recordedIdSet.contains(searchResultView.getRecordId().toString())) {

                    System.out.println("RECORD ID --- > " + searchResultView.getRecordId().toString());
                    executionReadyList.add(searchResultView);
                }
            }

            final RecordedAPIInvocationHandler handler = new RecordedAPIInvocationHandler();
            final List<RecordAndPlayExecutionResultView> executionResultView = handler.process(executionReadyList);

            if (null != getSession().getAttribute(SessionRegistry.RECORD_AND_PLAY_EXECUTION_RESULT_VIEW)) {
                
                final List<RecordAndPlayExecutionResultView> oldResultViewCollection = (List<RecordAndPlayExecutionResultView>) getSession().getAttribute(SessionRegistry.RECORD_AND_PLAY_EXECUTION_RESULT_VIEW);
                executionResultView.addAll(oldResultViewCollection);
            }
            
            getSession().setAttribute(SessionRegistry.RECORD_AND_PLAY_EXECUTION_RESULT_VIEW, executionResultView);

        }

        return "redirect:recordandplay_execute_result.htm";

    }
    
    /**
     * The method handle font end Ajax call.
     * 
     * @param model
     * @return
     */
    @RequestMapping(value = "/feed_hidden_data_selecthistry_record", method = RequestMethod.GET)
    public void feedHiddenData(@RequestParam("recordId") String recordId) {

        Set<String> recordedIdSet = null;

        if (null != getSession().getAttribute(SessionRegistry.RECORD_AND_PLAY_HISTORY_RECORD_SELECTION)) {

            recordedIdSet = (Set<String>) getSession().getAttribute(SessionRegistry.RECORD_AND_PLAY_HISTORY_RECORD_SELECTION);
        }

        if (!recordedIdSet.remove(recordId)) {
            recordedIdSet.add(recordId);
        }

        for (final String id : recordedIdSet) {
            System.out.println("SELECTED ID :" + id);
        }
        
        getSession().setAttribute(SessionRegistry.RECORD_AND_PLAY_HISTORY_RECORD_SELECTION, recordedIdSet);

    }
    


    @RequestMapping(value = "/downloadExecuteResultXML", method = RequestMethod.GET)
    public String downloadExecuteResultFile(final HttpServletRequest request, HttpServletResponse response,
        @ModelAttribute("RecordAndPlayModel") final RecordAndPlayModel model, final BindingResult result) throws IOException {

      final List<RecordAndPlayExecutionResultView> recordAndPlayExecutionResultViewCollection =
            (List<RecordAndPlayExecutionResultView>) getSession().getAttribute(SessionRegistry.RECORD_AND_PLAY_EXECUTION_RESULT_VIEW);

        final String id = (String) request.getParameter("RecordId");
        RecordAndPlayExecutionResultView selectedRecordAndPlayExecutionResultView = null;

        for (final RecordAndPlayExecutionResultView recordAndPlayExecutionView : recordAndPlayExecutionResultViewCollection) {

            if (recordAndPlayExecutionView.getRecordId().equals(Long.valueOf(id))) {
                selectedRecordAndPlayExecutionResultView = recordAndPlayExecutionView;
                break;
            }

        }

        logger.info("Result=>" + selectedRecordAndPlayExecutionResultView.getResult());
        logger.info("Record id>" + selectedRecordAndPlayExecutionResultView.getRecordId());

        response.setContentType("application/xml");
        response.addHeader("Content-disposition",
            "atachment; filename=APIExecution_Result_ApiName_" + selectedRecordAndPlayExecutionResultView.getApiName() + ".txt");

        final OutputStream buffoutput = new BufferedOutputStream(response.getOutputStream());
        final OutputStreamWriter outputwriter = new OutputStreamWriter(buffoutput);

        final CommonFileHandler fileHandler = new CommonFileHandler();
        final StringBuilder stringBuilder = fileHandler.read(selectedRecordAndPlayExecutionResultView.getLocation());

        outputwriter.write(stringBuilder.toString());

        outputwriter.flush();
        outputwriter.close();

        return "recordandplaylayout";

    }
    
    
    @RequestMapping(value = "/downloadSearchResultXML", method = RequestMethod.GET)
    public String downloadSearchResultFile(final HttpServletRequest request, HttpServletResponse response,@ModelAttribute("RecordAndPlayModel") final RecordAndPlayModel model, final BindingResult result) throws IOException {

        final List<SearchResultView> recordAndPlaySearchResultViewCollection =
            (List<SearchResultView>) getSession().getAttribute(SessionRegistry.RECORD_AND_PLAY_SERACH_VIEW);

        final String id = (String) request.getParameter("RecordId");
        SearchResultView selectedSearchResultView = null;

        for (final SearchResultView searchResultView : recordAndPlaySearchResultViewCollection) {

            if (searchResultView.getRecordId().equals(Long.valueOf(id))) {
                selectedSearchResultView = searchResultView;
                break;
            }

        }

        logger.info("Record id>" + selectedSearchResultView.getRecordId());

        response.setContentType("application/xml");
        response
            .addHeader("Content-disposition", "atachment; filename=APIExecution_Search_ApiName_" + selectedSearchResultView.getApiName() + ".txt");

        final OutputStream buffoutput = new BufferedOutputStream(response.getOutputStream());
        final OutputStreamWriter outputwriter = new OutputStreamWriter(buffoutput);

        final CommonFileHandler fileHandler = new CommonFileHandler();
        final StringBuilder stringBuilder = fileHandler.read(selectedSearchResultView.getLocation());

        outputwriter.write(stringBuilder.toString());

        outputwriter.flush();
        outputwriter.close();

        return "recordandplaylayout";        
        
    }


}
